$S.WindowManager = function(){
    return {
        put : function(win){
        	if(!this.cache) this.cache = [];
        	this.cache.add(win)
        },
        getAll : function(){
        	return this.cache;
        },
        remove : function(win){
        	this.cache.remove(win);
        },
        get : function(id){
        	if(!this.cache) return null;
        	var win = null;
        	for(var i = 0;i<this.cache.length;i++){
    			if(this.cache[i].id == id) {
	        		win = this.cache[i];
    				break;      			
        		}
        	}
        	return win;
        },
        getZindex: function(){
        	var zindex = 40;
        	var all = this.getAll();
            if(all)
        	for(var i = 0;i<all.length;i++){
        		var win = all[i];
        		var zd = win.wrap.getStyle('z-index');
        		zd = (zd =='auto') ? 0 : Number(zd);
        		if(zd > zindex) zindex = zd;       		
        	}
        	return Number(zindex);
        }
    };
}();
/**
 * @class Spark.Window
 * @extends Spark.Component
 * <p>窗口组件.
 * @author njq.niu@hand-china.com
 * @constructor
 * @param {Object} config 配置对象. 
 */
$S.Window = Ext.extend($S.ViewComponent,{
    focusCss:'w_fs',
	constructor: function(config) { 
		if($S.WindowManager.get(config.id))return;
        this.draggable = true;
        this.closeable = true;
        this.hasCloseBtn = true;
        this.fullScreen = false;
        this.modal = config.modal||true;
        this.className = config.className||'';
        this.cmps = {};
//        $S.focusWindow = null;
        $S.Window.superclass.constructor.call(this,config);
    },
    initComponent : function(config){
        var sf = this; 
        $S.WindowManager.put(sf);
        $S.Window.superclass.initComponent.call(this, config);
    	var windowTpl = new Ext.Template(sf.getTemplate());
    	sf.width = 1*(sf.width||350);
    	sf.height= 1*(sf.height||400);
    	if(sf.fullScreen){
    		sf.width=$S.getViewportWidth()-(Ext.isIE||!sf.hasVScrollBar()?0:17)-(Ext.isIE8?1:0);
    		sf.height=$S.getViewportHeight()-(Ext.isIE||!sf.hasHScrollBar()?26:43);
    		sf.draggable = false;
    		sf.marginHeight=1;
    		sf.marginWidth=1;
    	}
        sf.wrap = windowTpl.insertFirst(document.body, {title:sf.title,className:sf.className,width:sf.width,bodywidth:sf.width-22,bodyheight:sf.height-42,height:sf.height}, true);
    	sf.title = sf.wrap.child('div[stype=window.title]');
    	sf.head = sf.wrap.child('td[stype=window.head]');
    	sf.body = sf.wrap.child('div[stype=window.body]');
        sf.closeBtn = sf.wrap.child('div[stype=window.close]');
        if(sf.draggable) sf.initDraggable();
        if(!sf.hasCloseBtn)sf.closeBtn.hide();
        sf.center();
        if(sf.url){
        	sf.showLoading();       
        	sf.load(sf.url,sf.params)
        }
    },
    processListener: function(ou){
    	$S.Window.superclass.processListener.call(this,ou);
    	if(this.closeBtn) {
    	   this.closeBtn[ou]("click", this.onCloseClick,  this);
    	   this.closeBtn[ou]("mouseover", this.onCloseOver,  this);
    	   this.closeBtn[ou]("mouseout", this.onCloseOut,  this);
    	   this.closeBtn[ou]("mousedown", this.onCloseDown,  this);
    	}
    	if(!this.modal) this.wrap[ou]("click", this.toFront, this);
    	this.wrap[ou]("keydown", this.handleKeyDown,  this);
    	if(this.draggable)this.head[ou]('mousedown', this.onMouseDown,this);
    },
    initEvents : function(){
    	$S.Window.superclass.initEvents.call(this);
    	this.addEvents(
    	/**
         * @event close
         * 窗口关闭事件.
         * @param {Window} this 当前窗口.         * 
         */
    	'close',
    	/**
         * @event load
         * 窗口加载完毕.
         * @param {Window} this 当前窗口.
         */
    	'load');    	
    },
    handleKeyDown : function(e){
		var key = e.getKey();
		if(key == 9){ //tab
            
            var fk,lk,ck,cmp
            for(var k in this.cmps){
                cmp = this.cmps[k];
                if(!fk && cmp.focus){
                    fk=k;
                }
                lk=k;
                if(cmp.isFocused){
                    ck = k;
                }
            }
            if(e.shiftKey){
                var temp = lk;
                lk = fk;
                fk = temp;
            }
            
            if(ck==lk){
                e.stopEvent();
                if(cmp && cmp.blur)cmp.blur();
                this.cmps[fk].focus();
            }
        }else if(key == 27){//esc
			this.close();
		}
    },
    initDraggable: function(){
    	this.head.addClass('draggable');
    },
//    /**
//     * 窗口获得焦点.
//     * 
//     */
//    focus: function(){
//		this.wrap.focus();
//	},
	/**
     * 窗口居中.
     * 
     */
    center: function(){
    	var screenWidth = $S.getViewportWidth();
    	var screenHeight = $S.getViewportHeight();
    	var sl = document[Ext.isStrict?'documentElement':'body'].scrollLeft;
    	var st = document[Ext.isStrict?'documentElement':'body'].scrollTop;
    	var x = sl+Math.max((screenWidth - this.width)/2,0);
    	var y = st+Math.max((screenHeight - this.height-(Ext.isIE?26:23))/2,0);
//        this.shadow.setWidth(this.wrap.getWidth());
//        this.shadow.setHeight(this.wrap.getHeight());
//        if(this.fullScreen){
//        	x=sl;y=st;
//        	this.shadow.moveTo(x,y)
//        }else {
//            this.shadow.moveTo(x+3,y+3)
//        }
        this.wrap.moveTo(x,y);
        this.toFront();
        //this.focus.defer(10,this);
    },
    hasVScrollBar : function(){
    	var body=document[Ext.isStrict?'documentElement':'body'];
    	return body.scrollTop>0||body.scrollHeight>body.clientHeight;
    },
    hasHScrollBar : function(){
    	var body=document[Ext.isStrict?'documentElement':'body'];
    	return body.scrollLeft>0||body.scrollWidth>body.clientWidth;
    },
//    getShadowTemplate: function(){
//    	return ['<DIV class="s_shadow"></DIV>']
//    },
    getTemplate : function() {
        return [
            '<table class="s_dialog {className}" style="left:-1000px;top:-1000px;width:{width}px;height:{height}px" tabIndex="-1" hidefocus cellSpacing="0" cellPadding="0" border="0">',
            '<tbody>',
                '<tr style="height:10px;">',
                    '<td class="s_dialog_tl"></td>',
                    '<td class="s_dialog_tc"></td>',
                    '<td class="s_dialog_tr"></td>',
                '</tr>',
                '<tr style="height:20px;">',
                    '<td class="s_dialog_hl"></td>',
                    '<td class="s_dialog_hc" stype="window.head" onselectstart="return false;" unselectable="on">',
                        '<DIV style="float:left;padding-left:4px;">{title}</DIV>',
                        '<DIV class="s_dialog_close" stype="window.close" style="float:right" unselectable="on"></DIV>',
                    '</td>',
                    '<td class="s_dialog_hr"></td>',
                '</tr>',
                '<tr style="height:{bodyheight}px">',
                    '<td class="s_dialog_cl"></td>',
                    '<td class="s_dialog_cc">',
                        '<div class="s_dialog_ct" stype="window.body" style="position:relatvie;width:{bodywidth}px;height:{bodyheight}px;" unselectable="on"></DIV>',
                    '</td>',    
                    '<td class="s_dialog_cr"></td>',
                '</tr>',
                '<tr style="height:10px;">',
                    '<td class="s_dialog_bl"></td>',
                    '<td class="s_dialog_bc"></td>',
                    '<td class="s_dialog_br"></td>',
                '</tr>',
            '</tbody>',
        '</table>'
        ];
    },
    
//    getTemplate : function() {
//        return [
//            '<TABLE class="win-wrap" style="width:{width}px;" cellSpacing="0" cellPadding="0" border="0">',
//			'<TBODY>',
//			'<TR style="height:23px;" >',
//				'<TD class="win-caption">',
//					'<TABLE cellSpacing="0" unselectable="on"  onselectstart="return false;" style="height:23px;-moz-user-select:none;"  cellPadding="0" width="100%" border="0" unselectable="on">',
//						'<TBODY>',
//						'<TR>',
//							'<TD unselectable="on" class="win-caption-label" stype="window.head" width="99%">',
//								'<A stype="win.focus" href="#" class="win-fs" tabIndex="-1"></A><DIV unselectable="on" stype="window.title" unselectable="on">{title}</DIV>',
//							'</TD>',
//							'<TD unselectable="on" class="win-caption-button" noWrap>',
//								'<DIV class="win-close" stype="window.close" unselectable="on"></DIV>',
//							'</TD>',
//							'<TD><DIV style="width:5px;"/></TD>',
//						'</TR>',
//						'</TBODY>',
//					'</TABLE>',
//				'</TD>',
//			'</TR>',
//			'<TR style="height:{height}px">',
//				'<TD class="win-body" vAlign="top" unselectable="on">',
//					'<DIV class="win-content" stype="window.body" style="position:relatvie;width:{bodywidth}px;height:{height}px;" unselectable="on"></DIV>',
//				'</TD>',
//			'</TR>',
//			'</TBODY>',
//		'</TABLE>'
//        ];
//    },
    /**
     * 窗口定位到最上层.
     * 
     */
    toFront : function(){ 
    	var myzindex = this.wrap.getStyle('z-index');
    	var zindex = $S.WindowManager.getZindex();
    	myzindex = (myzindex =='auto') ?  0 : Number(myzindex);
    	if(myzindex < zindex) {
	    	this.wrap.setStyle('z-index', zindex+5);
//	    	this.shadow.setStyle('z-index', zindex+4);
	    	if(this.modal) $S.Cover.cover(this.wrap,this.opacity);
    	}
//    	$S.focusWindow = this;    	
    },
    onMouseDown : function(e){
    	var sf = this; 
    	//e.stopEvent();
    	sf.toFront();
    	var xy = sf.wrap.getXY();
    	sf.relativeX=xy[0]-e.getPageX();
		sf.relativeY=xy[1]-e.getPageY();
		sf.screenWidth = $S.getViewportWidth();
        sf.screenHeight = $S.getViewportHeight();
        if(!sf.proxy) sf.initProxy();
        sf.proxy.show();
        Ext.get(document.documentElement).on("mousemove", sf.onMouseMove, sf);
        Ext.get(document.documentElement).on("mouseup", sf.onMouseUp, sf);
    	sf.focus();
        
    },
    onMouseUp : function(e){
    	var sf = this; 
    	Ext.get(document.documentElement).un("mousemove", sf.onMouseMove, sf);
    	Ext.get(document.documentElement).un("mouseup", sf.onMouseUp, sf);
    	if(sf.proxy){
    		sf.wrap.moveTo(sf.proxy.getX(),sf.proxy.getY());
//    		sf.shadow.moveTo(sf.proxy.getX()+3,sf.proxy.getY()+3);
	    	sf.proxy.hide();
    	}
    },
    onMouseMove : function(e){
    	e.stopEvent();
    	var sl = document[Ext.isStrict?'documentElement':'body'].scrollLeft;
    	var st = document[Ext.isStrict?'documentElement':'body'].scrollTop;
    	var sw = sl + this.screenWidth;
    	var sh = st + this.screenHeight;
    	var tx = e.getPageX()+this.relativeX;
    	var ty = e.getPageY()+this.relativeY;
    	if(tx<=sl) tx =sl;
    	if((tx+this.width)>= (sw-3)) tx = sw - this.width - 3;
    	if(ty<=st) ty =st;
    	if((ty+this.height)>= (sh-3)) ty = Math.max(sh - this.height,0);
    	this.proxy.moveTo(tx,ty);
    },
    showLoading : function(){
    	this.body.update('正在加载...');//TODO:多语言
    	this.body.setStyle('text-align','center');
    	this.body.setStyle('line-height',5);
    },
    clearLoading : function(){
    	this.body.update('');
    	this.body.setStyle('text-align','');
    	this.body.setStyle('line-height','');
    },
    initProxy : function(){
    	var sf = this; 
    	var p = '<DIV class="s_dialog_proxy" onselectstart="return false;" unselectable="on"><div class="s_dialog_proxy_body"></div></DIV>'
    	sf.proxy = Ext.get(Ext.DomHelper.insertFirst(Ext.getBody(),p));
//    	sf.proxy.hide();
    	var xy = sf.wrap.getXY();
    	sf.proxy.setWidth(sf.wrap.getWidth());
    	sf.proxy.setHeight(sf.wrap.getHeight());
    	sf.proxy.setLocation(xy[0], xy[1]);
    },
    onCloseClick : function(e){
        e.stopEvent();
    	this.close(); 	
    },
    onCloseOver : function(e){
        this.closeBtn.addClass("s_dialog_close_over");
    },
    onCloseOut : function(e){
    	this.closeBtn.removeClass("s_dialog_close_over");
    },
    onCloseDown : function(e){
        e.stopEvent();
    	//this.closeBtn.removeClass("s_dialog_close_over");
    },
    close : function(){
        if(this.closeable) {
            $S.WindowManager.remove(this);
            this.destroy(); 
            this.fireEvent('close', this)
        }else{
            $S.showWarningMessage('提示','当前窗口正在执行后台程序,无法关闭!',null, 350);
        }
    },
    destroy : function(){
//    	$S.focusWindow = null;
    	var wrap = this.wrap;
    	if(!wrap)return;
    	if(this.proxy) this.proxy.remove();
    	if(this.modal) $S.Cover.uncover(this.wrap);
        for(var key in this.cmps){
            var cmp = this.cmps[key];
            if(cmp.destroy){
                try{
                    cmp.destroy();
                }catch(e){
                    alert('销毁window出错: ' + e)
                }
            }
        }
    	$S.Window.superclass.destroy.call(this);
    	delete this.title;
    	delete this.head;
    	delete this.body;
        delete this.closeBtn;
        delete this.proxy;
        wrap.remove();
//        var sf = this;
//        setTimeout(function(){
//        	for(var key in sf.cmps){
//        		var cmp = sf.cmps[key];
//        		if(cmp.destroy){
//        			try{
//        				cmp.destroy();
//        			}catch(e){
//        				alert('销毁window出错: ' + e)
//        			}
//        		}
//        	}
//        },10)
    },
    /**
     * 窗口加载.
     * 
     * @param {String} url  加载的url
     * @param {Object} params  加载的参数
     */
    load : function(url,params){
//    	var cmps = $S.CmpManager.getAll();
//    	for(var key in cmps){
//    		this.oldcmps[key] = cmps[key];
//    	}
        var pa = params||{};
        pa['_sph'] = $S.viewHeight;
        pa['_spw'] = $S.viewWidth;
        pa['SUK'] = $S.suk;
    	Ext.Ajax.request({
			url: url,
            method: 'POST',
			params:pa||{},
		   	success: this.onLoad.createDelegate(this)
		});		
    },
    setChildzindex : function(z){
    	for(var key in this.cmps){
    		var c = this.cmps[key];
    		c.setZindex(z)
    	}
    },
    setWidth : function(w){
    	//w=$S.getViewportWidth()-(Ext.isIE||!this.hasVScrollBar()?0:17)-(Ext.isIE8?1:0);
    	$S.Window.superclass.setWidth.call(this,w);
    	this.body.setWidth(w-2);
//    	this.shadow.setWidth(this.wrap.getWidth());
    },
    setHeight : function(h){
    	h=$S.getViewportHeight()-(Ext.isIE||!this.hasHScrollBar()?26:43);
    	Ext.fly(this.body.dom.parentNode.parentNode).setHeight(h);
    	this.body.setHeight(h);
//        this.shadow.setHeight(this.wrap.getHeight());
    	var sl = document[Ext.isStrict?'documentElement':'body'].scrollLeft;
    	var st = document[Ext.isStrict?'documentElement':'body'].scrollTop;
//        this.shadow.moveTo(sl,st);
        this.wrap.moveTo(sl,st);
    },
    onLoad : function(response, options){
    	if(!this.body) return;
    	this.clearLoading();
    	var html = response.responseText;
    	var res
    	try {
            res = Ext.decode(response.responseText);
        }catch(e){}
        if(res && res.success == false){
        	if(res.error){
        		$S.manager.fireEvent('ajaxfailed', $S.manager, options.url,options.para,res);
                var st = res.error.stackTrace;
                st = (st) ? st.replaceAll('\r\n','</br>') : '';
                if(res.error.message) {
                    var h = (st=='') ? 150 : 250;
                    $S.showErrorMessage('错误', res.error.message+'</br>'+st,null,400,h);//TODO:多语言
                }else{
                    $S.showErrorMessage('错误', st,null,400,250);
                }   
            }
            return;
        }
    	var sf = this
    	this.body.update(html,true,function(){
//	    	var cmps = $S.CmpManager.getAll();
//	    	for(var key in cmps){
//	    		if(sf.oldcmps[key]==null){	    			
//	    			sf.cmps[key] = cmps[key];
//	    		}
//	    	}
	    	sf.fireEvent('load',sf);
            sf.focus();
    	},this);
    }
});
/**
 * 
 * 显示提示信息窗口
 * 
 * @param {String} title 标题
 * @param {String} msg 内容
 * @param {Function} callback 回调函数
 * @param {int} width 宽度
 * @param {int} height 高度
 * @return {Window} 窗口对象
 */
$S.showMessage = function(title, msg,callback,width,height){
	return $S.showTypeMessage(title, msg, width||300, height||150,'win-info',callback);
}
/**
 * 显示带警告图标的窗口
 * 
 * @param {String} title 标题
 * @param {String} msg 内容
 * @param {Function} callback 回调函数
 * @param {int} width 宽度
 * @param {int} height 高度
 * @return {Window} 窗口对象
 */
$S.showWarningMessage = function(title, msg,callback,width,height){
	return $S.showTypeMessage(title, msg, width||300, height||150,'win-warning',callback);
}
/**
 * 显示带信息图标的窗口
 * 
 * @param {String} title 标题
 * @param {String} msg 内容
 * @param {Function} callback 回调函数
 * @param {int} width 宽度
 * @param {int} height 高度
 * @return {Window} 窗口对象
 */
$S.showInfoMessage = function(title, msg,callback,width,height){
	return $S.showTypeMessage(title, msg, width||300, height||150,'win-info',callback);
}
/**
 * 显示带错误图标的窗口
 * 
 * @param {String} title 标题
 * @param {String} msg 内容
 * @param {Function} callback 回调函数
 * @param {int} width 宽度
 * @param {int} height 高度
 * @return {Window} 窗口对象
 */
$S.showErrorMessage = function(title,msg,callback,width,height){
	return $S.showTypeMessage(title, msg, width||300, height||150,'win-error',callback);
}

$S.showTypeMessage = function(title, msg,width,height,css,callback){//width:'+(width-100)+'px;
	var msg = '<div class="win-icon '+css+'" style="height:'+(height-100)+'px;"><div class="win-type" style="height:'+(height-100)+'px;">'+msg+'</div></div>';
	return $S.showOkWindow(title, msg, width, height,callback);	
} 
/**
 * 带图标的确定窗口.
 * 
 * @param {String} title 标题
 * @param {String} msg 内容
 * @param {Function} okfun 确定的callback
 * @param {Function} cancelfun 取消的callback
 * @param {int} width 宽度
 * @param {int} height 高度
 * @return {Window} 窗口对象
 */
$S.showConfirm = function(title, msg, yesFun,noFun, width, height, showCancle){
	width = width||350;
	height = height||150; //width:'+(width-100)+'px;
    var msg = '<div class="win-icon win-question" style="height:'+(height-100)+'px;"><div class="win-type" style="height:'+(height-100)+'px;">'+msg+'</div></div>';
    return $S.showYesNoCancelWindow(title, msg, yesFun,noFun, showCancle||false,width, height);  	
}
/**
 * 带确定取消按钮的窗口.
 * 
 * @param {String} title 标题
 * @param {String} msg 内容
 * @param {Function} okfun 确定的callback
 * @param {Function} cancelfun 取消的callback
 * @param {int} width 宽度
 * @param {int} height 高度
 * @return {Window} 窗口对象
 */
$S.showYesNoCancelWindow = function(title, msg, yesFun,noFun,showCancle,width, height){
    var id = Ext.id();
    var wid = 'spark-yes-no-cancel-' + id;
    var yid = 'spark-yes-'+id;
    var nid = 'spark-no-'+id;
    var cid = 'spark-cancle-'+id;
    //var cmp = $S.CmpManager.get('spark-msg-ok-cancel')
    //if(cmp == null) {
        var cmp = new $S.Window({id:wid,title:title, height:height||100,width:width||300,hasCloseBtn:false});
        if(msg){
            cmp.body.update(msg+ '<center><table cellspacing="5"><tr><td>'+$S.Button.getTemplate(yid,'是')+'</td><td>&nbsp;</td><td>'+$S.Button.getTemplate(nid,'否')+'</td>'+((showCancle) ? '<td>&nbsp;</td><td>'+$S.Button.getTemplate(cid,'取消')+'</td>' : '')+'</tr></table></center>',true,function(){
                var yesBtn = $(yid);
                var noBtn = $(nid);
                cmp.cmps[yid] = yesBtn;
                cmp.cmps[nid] = noBtn;
                yesBtn.on('click',function(){
                	if(yesFun)yesFun.call(this,cmp);
                });
                noBtn.on('click',function(){
                	if(noFun) {
                        noFun.call(this,cmp)
                    }else{
                        cmp.close();                        
                    }
                });
                if(showCancle){
                    var cBtn = $(cid);
                    cmp.cmps[cid] = cBtn;
                    cBtn.on('click',function(){
                        cmp.close();
                    });
                }
            });
        }
    //}
    return cmp;
}
/**
 * 带确定按钮的窗口.
 * 
 * @param {String} title 标题
 * @param {String} msg 内容
 * @param {Function} okfun 确定的callback
 * @param {Function} cancelfun 取消的callback
 * @param {int} width 宽度
 * @param {int} height 高度
 * @return {Window} 窗口对象
 */
$S.showOkWindow = function(title, msg, width, height,callback){
    var id = Ext.id();
    var wid = 'spark-msg-ok-' + id;
    var oid = 'spark-ok-'+id;
	//var cmp = $S.CmpManager.get('spark-msg-ok');
	//if(cmp == null) {
		var btnhtml = $S.Button.getTemplate(oid,'确定');//TODO:多语言
		var cmp = new $S.Window({id:wid,title:title, height:height,width:width,hasCloseBtn:false});
		if(msg){
			cmp.body.update(msg+ '<center>'+btnhtml+'</center>',true,function(){
    			var btn = $(oid);
                cmp.cmps[oid] = btn;
                btn.on('click',function(){
                    if(callback){
                        callback.call(this,cmp);
                    }else{
                        cmp.close()                        
                    }
                });
                btn.focus.defer(10,btn);
			});
		}
	//}
	return cmp;
}
/**
 * 上传附件窗口.
 * 
 * @param {String} path  当前的context路径
 * @param {String} title 上传窗口标题
 * @param {int} pkvalue  pkvalue
 * @param {String} source_type source_type
 * @param {int} max_size 最大上传大小(单位kb)  0表示不限制
 * @param {String} file_type 上传类型(*.doc,*.jpg)
 * @param {String} callback 回调函数的名字
 */
$S.showUploadWindow = function(path,title,source_type,pkvalue,max_size,file_type,callback){
    new Spark.Window({id:'upload_window', url:path+'/upload.screen?callback='+callback+'&pkvalue='+pkvalue+'&source_type='+source_type+'&max_size='+(max_size||0)+'&file_type='+(file_type||'*.*'), title:title||_lang['window.upload.title'], height:330,width:595});
}